<?php
namespace app\api\services;

use app\api\cache\Marketing;
use app\api\cache\MemberAccountCache;
use app\api\cache\MemberCache;
use app\api\consDir\CommunityConst;
use app\common\libs\Singleton;
use app\common\models\Community\Community;
use app\common\models\Community\CommunityOrder;
use app\common\models\Community\CommunityUser;
use app\common\models\Member\Account;
use app\common\models\Member\Address;
use app\common\models\Member\BaseUserUpgrade;
use app\common\models\Member\Finance;
use app\common\models\Member\Member;
use app\common\models\Member\MemberActivityLog;
use app\common\models\Member\MemberAgency;
use app\common\models\Member\MemberAmountLog;
use app\common\models\Member\MemberCommunityAmountLog;
use app\common\models\Member\MemberDeductionAmountLog;
use app\common\models\Member\MemberDigitalMoneyLog;
use app\common\models\Member\MemberDigitalScoreLog;
use app\common\models\Member\MemberEarningsLog;
use app\common\models\Member\MemberGxzLog;
use app\common\models\Member\MemberProfitLog;
use app\common\models\Member\MemberProfitPoolLog;
use app\common\models\Member\MemberScoreLog;
use app\common\models\Member\MemberShopAmountLog;
use app\common\models\Member\MemberSignInLog;
use app\common\models\Member\StatsInviteManage;
use app\common\models\Order\OrderPay;
use app\common\models\Order\OrderShop;
use app\common\models\Service\ServiceAmountLog;
use app\common\models\Shop\Shop;
use app\data\model\SendCommunityUser;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;
use think\Model;

class MemberService
{
    use Singleton;

    public function getUserAmountSum($userId, $status, $logStatus, $startAt, $endAt): float
    {
        $where = [
            ['user_id', '=', $userId],
            ['status', '=', $status],
        ];
        if ( ! empty($startAt)) {
            $where[] = ['create_at', 'between', [$startAt, $endAt]];
        }
        switch ($logStatus) {
            case "earnings":
                $amount = MemberEarningsLog::getInstance()->where($where)->sum('amount');
                break;
            case "score":
                $amount = MemberScoreLog::getInstance()->where($where)->sum('amount');
                break;
            default:
                $amount = MemberAmountLog::getInstance()->where($where)->sum('amount');

        }
        return $amount;
    }

    public function getAmountSum($userId, $status, $isToday = 0): float
    {
        $where = [
            ['user_id', '=', $userId],
            ['status', '=', $status],
        ];
        if ($isToday) {
            $where[] = ['create_at', '>', date('Y-m-d')];
        }
        return MemberAmountLog::getInstance()->where($where)->sum('amount');
    }

    public function getAmountLogSum($userId, $status, $isToday = 0, $type = 0): float
    {
        $where = [
            ['user_id', '=', $userId],
            ['status', '=', $status],
            ['type', '=', $type],
        ];
        if ($type == 0) {
            //$where[] = ['log_type', '<>', 'community_premium'];
        }
        if ($isToday) {
            $where[] = ['create_at', '>', date('Y-m-d')];
        }
        return bcadd(MemberCommunityAmountLog::getInstance()->where($where)->sum('amount'), 0, 4);
    }

    public function getGxzLogSum($userId, $status, $isToday = 0): float
    {
        $where = [
            ['user_id', '=', $userId],
            ['status', '=', $status],
        ];
        if ($isToday) {
            $where[] = ['create_at', '>', date('Y-m-d')];
        }
        return bcadd(MemberGxzLog::getInstance()->where($where)->sum('amount'), 0, 4);
    }

    public function getAmountDigitalLogSum($userId, $status, $isToday = 0, $type = 0): float
    {
        $where = [
            ['user_id', '=', $userId],
            ['status', '=', $status],
        ];
        if ($isToday) {
            $where[] = ['create_at', '>', date('Y-m-d')];
        }
        if ($type == 1) {
            $db = MemberDigitalMoneyLog::getInstance();
        } else {
            $db = MemberDigitalScoreLog::getInstance();
        }
        return $db->where($where)->sum('amount');
    }

    public function getDirectMembers($userId): int
    {
        return Member::getInstance()->where(['invite_id' => $userId])->count('id');
    }

    public function getDirectShop($userId): int
    {
        return Member::getInstance()->where(['invite_id' => $userId, 'is_shop' => 1])->count('id');
    }

    /**
     * 余额类型
     * @return array[]
     */
    public function logType(): array
    {
        return [
            [
                'name' => '收入',
                'list' => [
                    ['key' => 'add_all', 'name' => '全部'],
                    ['key' => 'withdraw_error', 'name' => '提现失败'],
                    ['key' => 'community_principal', 'name' => '社区转让本金'],
                    ['key' => 'community_withdraw', 'name' => '社区绿色积分兑换'],
                    ['key' => 'packs_withdraw', 'name' => '礼包绿色积分兑换'],
                    ['key' => 'spread_withdraw', 'name' => '推广绿色积分兑换'],
                    ['key' => 'bonus_withdraw', 'name' => '分红绿色积分兑换'],
                    ['key' => 'recharge', 'name' => '余额充值'],
                    ['key' => 'refund_order', 'name' => '售后订单退款'],
                    ['key' => 'prepay_refund', 'name' => '预约退还'],
                    ['key' => 'lottery_add', 'name' => '抽奖赠送'],
                    ['key' => 'prepay_refund', 'name' => '预约退还'],
                    ['key' => 'red_change', 'name' => '红包兑换'],
                    ['key' => 'earnings_change', 'name' => '收益兑换'],
                    ['key' => 'back_inc', 'name' => '后台添加'],
                ],
            ],
            [
                'name' => '支出',
                'list' => [
                    ['key' => 'reduce_all', 'name' => '全部'],
                    ['key' => 'change', 'name' => '提现'],
                    ['key' => 'pay_service', 'name' => '支付服务费'],
                    ['key' => 'pay_community', 'name' => '竞拍社区抵扣'],
                    ['key' => 'pay_offline', 'name' => '线下消费抵扣'],
                    ['key' => 'pay_online', 'name' => '线上消费抵扣'],
                    ['key' => 'pay_packs', 'name' => '购买礼包抵扣'],
                    ['key' => 'change_bag', 'name' => '兑换到个人电子钱包'],
                    ['key' => 'pay_carefree', 'name' => '无忧订单抵扣'],
                    ['key' => 'pay_card', 'name' => '会员卡订单抵扣'],
                    ['key' => 'back_dec', 'name' => '后台扣除'],
                ],
            ],
        ];
    }

    public function logDigitalAssetType(): array
    {
        return [
            [
                'name' => '收入',
                'list' => [
                    ['key' => 'add_all', 'name' => '全部'],
                    ['key' => 'packs', 'name' => '购买礼包赠送'],
                ],
            ],
        ];
    }

    public function logDigitalScoreType(): array
    {
        return [
            [
                'name' => '收入',
                'list' => [
                    ['key' => 'add_all', 'name' => '全部'],
                    ['key' => 'packs', 'name' => '购买礼包赠送'],
                    ['key' => 'online', 'name' => '线上订单'],
                    ['key' => 'offline', 'name' => '线下订单'],
                ],
            ],
        ];
    }

    /**
     * @param $communityId
     * @return array|false
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getCommunityAgencyInfo($communityId)
    {
        $community = CommunityService::getInstance()->getCommunity($communityId);
        if (empty($community)) {
            return false;
        }
        $provinceEarnings = CommunityService::getInstance()->getCommunityConfig('province_community_earnings');
        $cityEarnings     = CommunityService::getInstance()->getCommunityConfig('city_community_earnings');
        $areaEarnings     = CommunityService::getInstance()->getCommunityConfig('area_community_earnings');
        //获取区代
        return $this->getAgency($community, $areaEarnings, $cityEarnings, $provinceEarnings);
    }

    /**
     * @param $userId
     * @return array|false
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getMyAgencyInfo($userId)
    {
        $default = [
            'provinceUid' => 0,
            'cityUid'     => 0,
            'countryUid'  => 0,
        ];
        $userInfo = $this->getUserInfo($userId);
        if (empty($userInfo)) {
            return $default;
        }
        $userInfo = Community::getInstance()->where('comm_id', $userInfo['commId'])->find();
        if (empty($userInfo)) {
            return $default;
        }
        $userInfo         = $userInfo->toArray();
        $provinceEarnings = CommunityService::getInstance()->getCommunityConfig('province_earnings');
        $cityEarnings     = CommunityService::getInstance()->getCommunityConfig('city_earnings');
        $areaEarnings     = CommunityService::getInstance()->getCommunityConfig('area_earnings');

        //获取区代
        return $this->getAgency($userInfo, $areaEarnings, $cityEarnings, $provinceEarnings);
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function getMyAgencyPacksInfo($userId): array
    {
        $default = [
            'provinceUid' => 0,
            'cityUid'     => 0,
            'countryUid'  => 0,
        ];
        $userInfo = $this->getUserInfo($userId);
        if (empty($userInfo)) {
            return $default;
        }
        $userInfo = Community::getInstance()->where('comm_id', $userInfo['commId'])->find();
        if (empty($userInfo)) {
            return $default;
        }
        $userInfo         = $userInfo->toArray();
        $provinceEarnings = PacksService::getInstance()->getPacksConfig('province_earnings');
        $cityEarnings     = PacksService::getInstance()->getPacksConfig('city_earnings');
        $areaEarnings     = PacksService::getInstance()->getPacksConfig('area_earnings');

        //获取区代
        return $this->getAgency($userInfo, $areaEarnings, $cityEarnings, $provinceEarnings);
    }

    /**
     * @param $agencyId
     * @param $agencyType
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getAgencyInfo($agencyId, $agencyType): array
    {
        switch ($agencyType) {
            case 1:
                $where = [
                    ['agency_type', '=', $agencyType],
                    ['province_id', '=', $agencyId],
                    ['status', '=', 1],
                    ['deleted', '=', 0],
                ];
                break;
            case 2:
                $where = [
                    ['agency_type', '=', $agencyType],
                    ['city_id', '=', $agencyId],
                    ['status', '=', 1],
                    ['deleted', '=', 0],
                ];
                break;
            case 4:
                $where = [
                    ['agency_type', '=', $agencyType],
                    ['street_id', '=', $agencyId],
                    ['status', '=', 1],
                    ['deleted', '=', 0],
                ];
                break;

            default:
                $where = [
                    ['agency_type', '=', $agencyType],
                    ['country_id', '=', $agencyId],
                    ['status', '=', 1],
                    ['deleted', '=', 0],
                ];
        }
        $agency = MemberAgency::getInstance()->where($where)->find();
        return empty($agency) ? [] : $agency->toArray();
    }

    public function getMyPartnerInfo($userId)
    {
        $userInfo = $this->getUserInfo($userId);
        if (empty($userInfo) || $userInfo['inviteId'] <= 0) {
            return false;
        }

        $ids         = explode("-", $userInfo['inviteIds']);
        $ids         = array_reverse($ids);
        $inviteInfos = $this->getUserInfoIds($ids);
        if (empty($inviteInfos)) {
            return false;
        }
        foreach ($ids as $val) {
            if ( ! $val || $val == $userId) {
                continue;
            }
            $inviteInfo = $inviteInfos[$val] ?? [];
            if (empty($inviteInfo)) {
                continue;
            }

            if ($inviteInfo['isPartner'] > 0) {
                return ['partnerType' => $inviteInfo['isPartner'], 'partnerId' => $val];
            }
        }
        return false;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function getMyPartner($member)
    {
        if (empty($member)) {
            return [];
        }
        $ids     = explode('-', $member['invite_ids']);
        $parents = Member::getInstance()->where('id', 'in', $ids)->order('id desc')->select();
        if (empty($parents)) {
            return [];
        }
        $parents = $parents->toArray();
        $arr     = [];
        $i       = 0;
        foreach ($parents as $v) {
            if ($v['isPartner']) {
                $i++;
            }
            if ($i == 2) {
                $arr = $v;
                break;
            }
        }
        return $arr;
    }

    public function getMyService($member)
    {
        if (empty($member)) {
            return [];
        }
        $ids     = explode('-', $member['invite_ids']);
        $parents = Member::getInstance()->where('id', 'in', $ids)->order('id desc')->select();
        if (empty($parents)) {
            return [];
        }
        $parents = $parents->toArray();
        $arr     = [];
        foreach ($parents as $v) {
            if ($v['isPartner']) {
                $arr = $v;
                break;
            }
        }
        return $arr;
    }

    /**
     * @param $userId
     * @param $type
     * @return Member
     */
    public function addUserPartner($userId, $type): Member
    {
        MemberCache::delUserInfo($userId);
        return Member::getInstance()->where('id', $userId)->update(['is_partner' => $type]);
    }

    public function account($userId): array
    {
        $where = [
            ['user_id', '=', $userId],
        ];
        $account = Account::getInstance()->where($where)->find();
        return empty($account) ? [] : $account->toArray();
    }

    public function createCode($user_id): string
    {
        static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
        $num                  = $user_id;
        $code                 = '';
        while ($num > 0) {
            $mod  = $num % 35;
            $num  = ($num - $mod) / 35;
            $code = $source_string[$mod] . $code;
        }
        if (empty($code[3])) {
            $code = str_pad($code, 6, '0', STR_PAD_LEFT);
        }

        return $code;
    }

    public function decode($code)
    {
        static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
        if (strrpos($code, '0') !== false) {
            $code = substr($code, strrpos($code, '0') + 1);
        }

        $len  = strlen($code);
        $code = strrev($code);
        $num  = 0;
        for ($i = 0; $i < $len; $i++) {
            $num += strpos($source_string, $code[$i]) * pow(35, $i);
        }
        return $num;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function addFinanceLog($userId, $type, $amount, $priceType, $msg = '', $orderNo = '', $modelType = 1, $fundType = 0,$twoAmount = 0): bool
    {
        if ($amount <= 0 && $twoAmount <= 0) {
            return false;
        }

        $finance = MemberService::getInstance()->finance($userId);
        if (empty($finance)) {
            return false;
        }
        //1余额 2商铺收益 3社区余额 4积分 5绿色积分 6数字资产、积分 7贡献值 8抵扣金
        switch ($priceType) {
            case 1:
                $this->addAmountInfo($finance, $type, $amount, $msg);
                break;
            case 2:
                $this->addShopAmountInfo($finance, $type, $amount, $msg);
                break;
            case 3:
                $this->addCommunityAmountInfo($finance, $type, $amount, $msg, $orderNo);
                break;
            case 4:
                $this->addScoreAmountInfo($finance, $type, $amount, $msg);
                break;
            case 5:
                $this->addGreenAmountInfo($finance, $type, $amount, $msg, $orderNo, $fundType);
                break;
            case 6:
                $this->addDigitalAmountInfo($finance, $type, $amount, $msg, $orderNo, $modelType);
                break;
            case 7:
                $this->addGxzAmountInfo($finance, $type, $amount, $msg, $orderNo);
                break;
            case 8:
                $this->addDeduction($finance, $type, $amount, $msg, $orderNo, $twoAmount);
                break;
            default:
        }
        return true;
    }

    protected function addScoreAmountInfo($finance, $type, $amount, $msg): bool
    {
        //判断是否减金额,
        $arr = [
        ];

        //判断是否要加总收入
        $allArr = [
            'order_task',
        ];
        $thisAmount = $finance['score'];

        $status = in_array($type, $arr) ? 2 : 1; //2减少

        if ($status == 1) {
            $alterAmount = bcadd($thisAmount, $amount, 2);
        } else {
            $alterAmount = bcsub($thisAmount, $amount, 2);
        }

        $data = [
            'user_id'      => $finance['userId'],
            'status'       => $status,
            'remark'       => $msg,
            'log_type'     => $type,
            'this_amount'  => $thisAmount,
            'alter_amount' => $alterAmount,
            'amount'       => $amount,
        ];
        MemberCommunityAmountLog::getInstance()->insert($data);

        if ($status == 1) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('score', $amount)->update();
        } else {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->dec('score', $amount)->update();
        }
        if (in_array($type, $allArr)) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('all_score', $amount)->update();
        }

        return true;
    }

    protected function addCommunityAmountInfo($finance, $type, $amount, $msg, $orderNo): bool
    {
        //判断是否减金额,
        $arr = [
            'withdraw', //社区提现到余额
            'sign_order', //余额支付
            'community_pay', //社区购买
            'service_pay', //服务商购买
            'sign_pay', //签到购买
            'change_bag',
        ];
        //判断是否要加总收入
        $allArr = [
            'community_principal', //社区转让本金
            'community_premium', //社区溢价
            'service_earnings', //服务商溢价收益
            'service_team_earnings', //服务商团队溢价收益
            'province_earnings', //用户省代理收益
            'city_earnings', //用户市代理收益
            'area_earnings', //用户区代理收益
            'business_earnings', //事业部收益
            'province_community_earnings', //社区省代理收益
            'city_community_earnings', //社区市代理收益
            'area_community_earnings', //社区区代理收益
            'business_community_earnings', //社区事业部收益
            'shop_earnings', //商家收益
            'sign_return', //签到退回
            'vip_earnings', //vip收益
        ];
        $thisAmount = $finance['communityAmount'];

        $status = in_array($type, $arr) ? 2 : 1; //2减少

        if ($status == 1) {
            $alterAmount = bcadd($thisAmount, $amount, 4);
        } else {
            $alterAmount = bcsub($thisAmount, $amount, 4);
        }

        $data = [
            'user_id'      => $finance['userId'],
            'status'       => $status,
            'remark'       => $msg . '当前绿色积分' . $alterAmount,
            'log_type'     => $type,
            'this_amount'  => $thisAmount,
            'alter_amount' => $alterAmount,
            'amount'       => $amount,
            'order_no'     => $orderNo,
        ];
        MemberCommunityAmountLog::getInstance()->insert($data);

        if ($status == 1) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('community_amount', $amount)->update();
        } else {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->dec('community_amount', $amount)->update();
        }
        if (in_array($type, $allArr)) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('all_community_amount', $amount)->update();
        }

        if ($status == 1) {
            $this->addAmount($type, $amount, $finance['userId']);
        }

        return true;
    }

    public function addAmount($type, $amount, $userId)
    {
        $updateField = '';

        if ($type == 'community_premium') {
            //社区收益
            $updateField = 'community_earnings';
        } else if (in_array($type, ['service_earnings', 'service_team_earnings'])) {
            //服务商收益
            $updateField = 'community_service_earnings';
        } elseif ($type == 'shop_earnings') {
            //商家收益
            $updateField = 'community_shop_earnings';
        } elseif (in_array($type, ['province_community_earnings', 'city_community_earnings', 'area_community_earnings'])) {
            //社区区域收益
            $updateField = 'community_area_earnings';
        } elseif (in_array($type, ['province_user_earnings', 'city_user_earnings', 'area_user_earnings'])) {
            //区域用户收益
            $updateField = 'community_area_user_earnings';
        }

        if ( ! $updateField) {
            return false;
        }
        return Finance::getInstance()->where(['user_id' => $userId])->inc($updateField, $amount)->update();
    }

    protected function addAmountInfo($finance, $type, $amount, $msg): bool
    {
        //判断是否减金额,
        $arr = [
            'pay',
            'change',
            //支付服务费
            'pay_service',
            'pay_community',
            'pay_offline',
            'pay_online',
            'pay_supply',
            'change_bag',
            'pay_packs',
            'pay_oc',
            'pay_card',
            'pay_carefree',
            'pay_services',
        ];

        //判断是否加总收入
        $allArr = [
            'community_withdraw',
            'order_task',
            'community_principal',
        ];
        $thisAmount = $finance['amount'];

        $status = in_array($type, $arr) ? 2 : 1; //2减少

        if ($status == 1) {
            $alterAmount = bcadd($thisAmount, $amount, 2);
        } else {
            $alterAmount = bcsub($thisAmount, $amount, 2);
        }
        $data = [
            'user_id'      => $finance['userId'],
            'status'       => $status,
            'remark'       => $msg . '，当前余额' . $alterAmount,
            'log_type'     => $type,
            'this_amount'  => $thisAmount,
            'alter_amount' => $alterAmount,
            'amount'       => $amount,
        ];
        MemberAmountLog::getInstance()->insert($data);
        if (in_array($type, $allArr)) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('all_amount', $amount)->update();
        }

        if ($status == 1) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('amount', $amount)->update();
        } else {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->dec('amount', $amount)->update();
        }

        return true;
    }

    protected function addGreenAmountInfo($finance, $type, $amount, $msg, $orderNo, $fundType = 0): bool
    {
        //判断是否减金额,
        $arr = [
            'change', //提现到余额
            'pay', //礼包购买
        ];
        $fundArr = [
            0 => $finance['communityAmount'],
            1 => $finance['giftBagAmount'],
            2 => $finance['inviteAmount'],
            3 => $finance['bonus'],
        ];
        $thisAmount = $fundArr[$fundType];
        $status     = in_array($type, $arr) ? 2 : 1; //2减少

        if ($status == 1) {
            $alterAmount = bcadd($thisAmount, $amount, 4);
        } else {
            $alterAmount = bcsub($thisAmount, $amount, 4);
        }

        $data = [
            'user_id'      => $finance['userId'],
            'status'       => $status,
            'remark'       => $msg . '，当前绿色积分' . $alterAmount,
            'log_type'     => $type,
            'this_amount'  => $thisAmount,
            'alter_amount' => $alterAmount,
            'amount'       => $amount,
            'order_no'     => $orderNo,
            'type'         => $fundType,
        ];
        MemberCommunityAmountLog::getInstance()->insert($data);
        switch ($fundType) {
            case 0:
                $field = 'community_amount';
                break;
            case 1:
                $field = 'gift_bag_amount';
                break;
            case 2:
                $field = 'invite_amount';
                break;
            case 3:
                $field = 'bonus';
                break;
            default:
                $field = '';
        }
        if ($status == 1) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc($field, $amount)->update();
        } else {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->dec($field, $amount)->update();
        }

        return true;
    }

    protected function addDigitalAmountInfo($finance, $type, $amount, $msg, $orderNo, $modelType): bool
    {
        //判断是否减金额,
        $arr = [
            'change', //提现到余额
            'pay', //购买
        ];
        if ($modelType == 1) {
            $db          = MemberDigitalMoneyLog::getInstance();
            $field       = 'digitalMoney';
            $str         = '资产';
            $updateField = 'digital_money';
        } else {
            $db          = MemberDigitalScoreLog::getInstance();
            $field       = 'digitalScore';
            $str         = '积分';
            $updateField = 'digital_score';
        }
        $thisAmount = $finance[$field];

        $status = in_array($type, $arr) ? 2 : 1; //2减少

        if ($status == 1) {
            $alterAmount = bcadd($thisAmount, $amount, 2);
        } else {
            $alterAmount = bcsub($thisAmount, $amount, 2);
        }

        $data = [
            'user_id'      => $finance['userId'],
            'status'       => $status,
            'remark'       => $msg . '，当前数字' . $str . $alterAmount,
            'log_type'     => $type,
            'this_amount'  => $thisAmount,
            'alter_amount' => $alterAmount,
            'amount'       => $amount,
            'order_no'     => $orderNo,
        ];
        $db->insert($data);

        if ($status == 1) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc($updateField, $amount)->update();
        } else {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->dec($updateField, $amount)->update();
        }

        return true;
    }

    protected function addActivityAmountInfo($finance, $type, $amount, $msg, $orderNo = ''): bool
    {
        if ($amount <= 0) {
            return false;
        }
        $thisAmount = $finance['activity'];

        //判断是否减金额,
        $arr = [
            'sign_in_no', //连续不签到
            'consume_no', //连续不消费
        ];

        $status = in_array($type, $arr) ? 2 : 1; //2减少
        if($finance['activity'] >= 100 && $status == 1){
            return false;
        }
        if($finance['activity'] <= 0 && $status == 2){
            return false;
        }

        if ($status == 1) {
            $alterAmount = bcadd($thisAmount, $amount, 2);
            if($alterAmount > 100){
                $remainAmount = bcsub($alterAmount,100,2);
                $amount = bcsub($amount,$remainAmount,2);
                $alterAmount = 100;
            }
        } else {
            if($thisAmount < $amount){
                $amount = $thisAmount;
            }
            $alterAmount = bcsub($thisAmount, $amount, 2);
        }

        $data = [
            'user_id'      => $finance['userId'],
            'status'       => $status,
            'remark'       => $msg . '，当前活跃值' . $alterAmount,
            'log_type'     => $type,
            'this_amount'  => $thisAmount,
            'alter_amount' => $alterAmount,
            'amount'       => $amount,
            'order_no'     => $orderNo,
        ];
        MemberActivityLog::getInstance()->insert($data);
        if ($status == 1) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('activity', $amount)->update();
        } else {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->dec('activity', $amount)->update();
        }
        return true;
    }

    protected function addGxzAmountInfo($finance, $type, $amount, $msg, $orderNo = ''): bool
    {
        //判断是否减金额,
        $arr = [
            'profit_sub',
            'lottery_dec',
        ];

        $thisAmount = $finance['gxz'];

        $status = in_array($type, $arr) ? 2 : 1; //2减少

        if ($status == 1) {
            $alterAmount = bcadd($thisAmount, $amount, 4);
        } else {
            $alterAmount = bcsub($thisAmount, $amount, 4);
        }
        $data = [
            'user_id'      => $finance['userId'],
            'status'       => $status,
            'remark'       => $msg . '，当前贡献值' . $alterAmount,
            'log_type'     => $type,
            'this_amount'  => $thisAmount,
            'alter_amount' => $alterAmount,
            'amount'       => $amount,
            'order_no'     => $orderNo,
        ];
        MemberGxzLog::getInstance()->insert($data);
        if ($status == 1) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('gxz', $amount)->update();
        } else {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->dec('gxz', $amount)->update();
        }
        return true;
    }

    public function addDeduction($finance, $type, $amount, $msg, $orderNo = '',$communityDeduction = 0): bool
    {
        if($amount > 0){
            return $this->addDeductionOne($finance, $type, $amount, $msg, $orderNo);
        }
        if($communityDeduction > 0){
            return $this->addDeductionTwo($finance, $type, $communityDeduction, $msg, $orderNo);
        }
        return true;
    }

    public function addDeductionOne($finance, $type, $amount, $msg, $orderNo = ''): bool
    {
        if($amount <= 0){
            return false;
        }
        //判断是否减金额,
        $arr = [
            'change', //提现到余额
            'buy', //购买商品抵扣
        ];
        $thisAmount = $finance['deduction'];
        $status     = in_array($type, $arr) ? 2 : 1; //2减少
        if ($status == 1) {
            $alterAmount = bcadd($thisAmount, $amount, 4);
        } else {
            $alterAmount = bcsub($thisAmount, $amount, 4);
        }
        $msg = $msg . "，当前平台抵扣券" . $alterAmount;
        $data = [
            'user_id'      => $finance['userId'],
            'status'       => $status,
            'remark'       => $msg,
            'log_type'     => $type,
            'this_amount'  => $thisAmount,
            'alter_amount' => $alterAmount,
            'amount'       => $amount,
            'order_no'     => $orderNo,
            'type'         => 0,
        ];
        MemberDeductionAmountLog::getInstance()->insert($data);
        if ($status == 1) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('deduction', $amount)->update();
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('all_deduction', $amount)->update();
        } else {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->dec('deduction', $amount)->update();
        }
        return true;
    }

    public function addDeductionTwo($finance, $type, $amount, $msg, $orderNo = ''): bool
    {
        if($amount <= 0){
            return false;
        }
        //判断是否减金额,
        $arr = [
            'change', //提现到余额
            'buy', //购买商品抵扣
        ];
        $thisAmount = $finance['communityDeduction'];
        $status     = in_array($type, $arr) ? 2 : 1; //2减少
        if ($status == 1) {
            $alterAmount = bcadd($thisAmount, $amount, 4);
        } else {
            $alterAmount = bcsub($thisAmount, $amount, 4);
        }
        $msg = $msg . "，当前社区抵扣券" . $alterAmount;
        $data = [
            'user_id'      => $finance['userId'],
            'status'       => $status,
            'remark'       => $msg,
            'log_type'     => $type,
            'this_amount'  => $thisAmount,
            'alter_amount' => $alterAmount,
            'amount'       => $amount,
            'order_no'     => $orderNo,
            'type'         => 1,
        ];
        MemberDeductionAmountLog::getInstance()->insert($data);
        if ($status == 1) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('community_deduction', $amount)->update();
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('all_community_deduction', $amount)->update();
        } else {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->dec('community_deduction', $amount)->update();
        }
        return true;
    }

    /**
     * 获取一堆用户消息
     * @param $ids
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getUserInfoIds($ids): array
    {
        $list = Member::getInstance()->where('id', 'in', $ids)->order('id desc')->select();
        if (empty($list)) {
            return [];
        } else {
            $list = $list->toArray();
        }
        $arr = [];
        foreach ($list as $val) {
            $val['phone'] = empty($val['phone']) ? '' : substr_replace($val['phone'], '****', 3, 4);
            $data         = [
                'id'        => $val['id'],
                'phone'     => $val['phone'],
                'avatar'    => $val['avatar'],
                'user_name' => $val['userName'],
                'userName'  => $val['userName'],
                'isPartner' => $val['isPartner'],
            ];
            $arr[$val['id']] = $data;
        }
        return $arr;
    }

    protected function addShopAmountInfo($finance, $type, $amount, $msg): bool
    {
        //判断是否减金额,
        $arr = [
            'charge',
        ];

        //判断是否要加总收入
        $allArr = [
            'order_task', //用户点确认收货
        ];

        $status     = in_array($type, $arr) ? 2 : 1; //2减少
        $thisAmount = $finance['shopAmount'] ?? $finance['shop_amount'];

        if ($status == 1) {
            $alterAmount = bcadd($thisAmount, $amount, 2);
        } else {

            $alterAmount = bcsub($thisAmount, $amount, 2);
        }

        $data = [
            'user_id'      => $finance['userId'],
            'status'       => $status,
            'remark'       => $msg,
            'log_type'     => $type,
            'this_amount'  => $thisAmount,
            'alter_amount' => $alterAmount,
            'amount'       => $amount,
        ];
        MemberShopAmountLog::getInstance()->insert($data);
        if ($status == 1) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('shop_amount', $amount)->update();
        } else {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->dec('shop_amount', $amount)->update();
        }
        if (in_array($type, $allArr)) {
            Finance::getInstance()->where(['user_id' => $finance['userId']])->inc('all_shop_amount', $amount)->update();
        }

        return true;
    }

    /**
     * @param $userId
     * @return array|Model
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function finance($userId)
    {
        $where = [
            ['user_id', '=', $userId],
        ];
        /*$field = 'user_id,friend_amount,shop_amount,community_amount,all_earnings,earnings
        ,amount,score,all_friend_amount,all_shop_amount,all_community_amount,all_score,all_amount
        ,community_earnings,community_shop_earnings,community_service_earnings,community_area_earnings
        ,community_area_user_earnings';*/
        $data = Finance::getInstance()
            ->where($where)
        //->field($field)
            ->find();

        if (empty($data)) {
            $data = [
                'score'                        => 0,
                'amount'                       => 0,
                'friend_amount'                => 0,
                'shop_amount'                  => 0,
                'community_amount'             => 0,
                'user_id'                      => $userId,
                'all_shop_amount'              => 0,
                'all_amount'                   => 0,
                'all_community_amount'         => 0,
                'all_friend_amount'            => 0,
                'all_score'                    => 0,
                'all_earnings'                 => 0,
                'earnings'                     => 0,
                'digital_score'                => 0,
                'red_packet'                   => 0,
                'digital_money'                => 0,
                'lianhe_score'                 => 0,
                'community_earnings'           => 0,
                'community_shop_earnings'      => 0,
                'community_service_earnings'   => 0,
                'community_area_earnings'      => 0,
                'community_area_user_earnings' => 0,
                'invite_amount'                => 0,
                'gift_bag_amount'              => 0,
                'gxz'                          => 0,
                'bonus'                        => 0,
                'day_bonus'                    => 0,
                'all_bonus'                    => 0,
                'deduction'                    => 0,
                'community_deduction'          => 0,
                'all_deduction'                => 0,
            ];
            Finance::getInstance()->insert($data);
        }
        // var_dump($data['red_packet']);exit;
        if ($data['red_packet'] <= 0) {
            $data['red_packet'] = \think\facade\Db::table('community_sign_user')
                ->where('user_id', $userId)
            //sign_status 1 未使用 2入驻已使用 3已返还到余额
                ->where('sign_status', 1)
                ->where('expire_at', '>', date('Y-m-d H:i:s'))
                ->sum('community_amount');
        }

        $data['red_packet'] = number_format($data['red_packet'], 2, '.', '');
        return [
            'score'                     => $data['score'],
            'amount'                    => $data['amount'],
            'friendAmount'              => $data['friend_amount'] ?? $data['friendAmount'],
            'shopAmount'                => $data['shop_amount'] ?? $data['shopAmount'],
            'communityAmount'           => $data['community_amount'] ?? $data['communityAmount'],
            'userId'                    => $data['user_id'] ?? $data['userId'],
            'allShopAmount'             => $data['all_shop_amount'] ?? $data['allShopAmount'],
            'allAmount'                 => $data['all_amount'] ?? $data['allAmount'],
            'allCommunityAmount'        => $data['all_community_amount'] ?? $data['allCommunityAmount'],
            'allFriendAmount'           => $data['all_friend_amount'] ?? $data['allFriendAmount'],
            'allScore'                  => $data['all_score'] ?? $data['allScore'],
            'allEarnings'               => $data['all_earnings'] ?? $data['allEarnings'],
            'earnings'                  => $data['earnings'],
            'digitalScore'              => $data['digital_score'] ?? '0.00',
            'redPacket'                 => $data['red_packet'] ?? '0.00',
            'digitalMoney'              => $data['digital_money'] ?? '0.00',
            'lianheScore'               => $data['lianhe_score'] ?? '0.0000', // 莲荷积分
            'langlangScore'             => $data['langlang_score'] ?? '0.0000', // 琅狼积分
            'communityEarnings'         => $data['community_earnings'] ?? '0.00',
            'communityShopEarnings'     => $data['community_shop_earnings'] ?? '0.00',
            'communityServiceEarnings'  => $data['community_service_earnings'] ?? '0.00',
            'communityAreaEarnings'     => $data['community_area_earnings'] ?? '0.00',
            'communityAreaUserEarnings' => $data['community_area_user_earnings'] ?? '0.00',
            'inviteAmount'              => $data['invite_amount'] ?? '0.0000',
            'giftBagAmount'             => $data['gift_bag_amount'] ?? '0.0000',
            'gxz'                       => $data['gxz'] ?? '0.0000',
            'bonus'                     => $data['bonus'] ?? '0.0000',
            'dayBonus'                  => $data['day_bonus'] ?? '0.0000',
            'allBonus'                  => $data['all_bonus'] ?? '0.0000',
            'activity'                  => $data['activity'] ?? '0.00',
            'deduction'                 => $data['deduction'] ?? '0.0000',
            'communityDeduction'       => $data['community_deduction'] ?? '0.0000',
            'allDeduction'              => $data['all_deduction'] ?? '0.0000',
        ];
    }

    /**
     * @param $userId
     * @param $addressId
     * @param int $type
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function addressDetail($userId, $addressId, int $type = 1): array
    {
        $where = [
            ['user_id', '=', $userId],
            ['id', '=', $addressId],
            ['deleted', '=', 0],
        ];
        if ($type == 1) {
            $field   = 'id,province,province_id,city,city_id,country,country_id,street,street_id,comm,comm_id,address,phone,real_name,is_default';
            $address = Address::getInstance()
                ->where($where)
                ->field($field)
                ->find();
            return empty($address) ? [] : $address->toArray();
        } else {
            $field   = 'province,province_id,city,city_id,country,country_id,street,street_id,comm,comm_id,address,phone,real_name';
            $address = Address::getInstance()
                ->where($where)
                ->column($field);
            return $address[0] ?? [];
        }

    }

    /**
     * @param $userId
     * @param $page
     * @param $pageSize
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function addressList($userId, $page, $pageSize): array
    {
        $where = [
            ['user_id', '=', $userId],
            ['deleted', '=', 0],
        ];
        $list = Address::getInstance()
            ->where($where)
            ->limit(($page - 1) * $pageSize, $pageSize)
            ->field('id,province,province_id,city,city_id,country,country_id,street,street_id,comm,comm_id,address,phone,real_name,is_default,address_type')
            ->order('is_default desc')
            ->select();
        return empty($list) ? [] : $list->toArray();
    }

    /**
     * @param $data
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getAccountInfo($data): array
    {
        $account = Account::getInstance()->where($data)->find();
        return empty($account) ? [] : $account->toArray();
    }

    /**
     * @param $userId
     * @param $data
     * @return Account|int|string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function editAccountVal($userId, $data)
    {
        $account = Account::getInstance()->where('user_id', '=', $userId)->find();
        if (empty($account)) {
            $data['user_id'] = $userId;
            return Account::getInstance()->insert($data);
        } else {
            return Account::getInstance()->where('user_id', '=', $userId)->update($data);
        }

    }

    /**
     * 修改用户信息
     * @param $userId
     * @param $data
     * @return Member
     */
    public function editVal($userId, $data)
    {
        MemberCache::delUserInfo($userId);
        return Member::getInstance()->where('id', '=', $userId)->update($data);
    }

    /**
     * 获取用户信息
     * @param $phone
     * @return array|mixed|string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getUserInfoByPhone($phone)
    {
        // $userData = MemberCache::getUserInfo($phone);
        // if ($userData) {
        //     return $userData;
        // }
        $userData = Member::getInstance()
            ->where('phone', '=', $phone)
            ->find();
        if (empty($userData)) {
            return [];
        }
        $userData = $userData->toArray();
        MemberCache::setUserInfo($phone, $userData);
        return $userData;
    }

    /**
     * 获取用户信息
     * @param $id
     * @return array|mixed|string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getUserInfo($id)
    {
        // $userData = MemberCache::getUserInfo($id);
        // if ($userData) {
        //     return $userData;
        // }
        $userData = Member::getInstance()
            ->where('id', '=', $id)
            ->field('id as user_id,user_name,phone,avatar,open_id,is_vip,is_partner,invite_id,invite_ids,invite_third_id,invite_code,create_at,province_id,city_id,country_id,street_id,comm_id,level')
            ->find();
        if (empty($userData)) {
            return [];
        }
        $userData = $userData->toArray();
        $level    = \think\facade\Db::table('base_user_upgrade')
            ->field(['name', 'icon'])
            ->where('number', $userData['level'])
            ->find();
        // var_dump($level);exit;
        $userData['levelName'] = $level['name'] ?? '';
        $userData['levelIcon'] = $level['icon'] ?? '';
        MemberCache::setUserInfo($id, $userData);
        return $userData;
    }

    /**
     * 获取用户信息
     * @param $openId
     * @return array|mixed|string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getUserInfoByOpenid($openId)
    {
        $userData = MemberCache::getUserInfo($openId);
        if ($userData) {
            return $userData;
        }
        $userData = Member::getInstance()
            ->where('open_id', '=', $openId)
            ->field('id as user_id,user_name,phone,avatar,open_id')
            ->find();
        if (empty($userData)) {
            return [];
        }
        $userData = $userData->toArray();
        MemberCache::setUserInfo($openId, $userData);
        return $userData;
    }

    /**
     * 更新用户信息
     * @param $id
     * @param $data
     */
    public function updateUser($id, $data)
    {
        Member::update($data, ['id' => $id]);
    }

    /**
     * @param array $community
     * @param $areaEarnings
     * @param $cityEarnings
     * @param $provinceEarnings
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function getAgency(array $community, $areaEarnings, $cityEarnings, $provinceEarnings): array
    {
        //获取区代
        $countryInfo = $this->getAgencyInfo($community['countryId'], 3);
        $countryName = empty($countryInfo) ? '' : $countryInfo['countryName'];

        if ($community['city'] == $community['country']) {
            $countryInfo = $this->getAgencyInfo($community['streetId'], 4);
            $countryName = empty($countryInfo) ? '' : $countryInfo['streetName'];
        }

        $countryUid      = empty($countryInfo) ? 0 : $countryInfo['userId'];
        $newAreaEarnings = empty($countryInfo) ? 0 : $areaEarnings;

        //获取市代
        $cityInfo        = $this->getAgencyInfo($community['cityId'], 2);
        $cityUid         = empty($cityInfo) ? 0 : $cityInfo['userId'];
        $cityName        = empty($cityInfo) ? '' : $cityInfo['cityName'];
        $newCityEarnings = empty($cityInfo) ? 0 : bcsub($cityEarnings, $newAreaEarnings, 2);

        //获取省代
        $provinceInfo = $this->getAgencyInfo($community['provinceId'], 1);
        $provinceUid  = empty($provinceInfo) ? 0 : $provinceInfo['userId'];
        $provinceName = empty($provinceInfo) ? '' : $provinceInfo['provinceName'];

        $newProvinceEarnings = empty($provinceInfo) ? 0 : bcsub(bcsub($provinceEarnings, $newCityEarnings, 2), $newAreaEarnings, 2);

        return [
            'provinceUid'      => $provinceUid,
            'cityUid'          => $cityUid,
            'countryUid'       => $countryUid,
            'provinceEarnings' => $newProvinceEarnings,
            'cityEarnings'     => $newCityEarnings,
            'areaEarnings'     => $newAreaEarnings,
            'provinceName'     => $provinceName,
            'cityName'         => $cityName,
            'countryName'      => $countryName,
        ];
    }

    /**
     * 获取省市区用户ID
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function getAgencyArr($provinceId, $cityId, $countryId, $streetId): array
    {
        //获取区代
        $countryInfo = $this->getAgencyInfo($countryId, 3);
        $countryUid  = empty($countryInfo) ? 0 : $countryInfo['userId'];
        $countryName = empty($countryInfo) ? '' : $countryInfo['countryName'];

        $countryInfo = $this->getAgencyInfo($streetId, 4);
        if ($countryInfo) {
            $countryUid  = empty($countryInfo) ? 0 : $countryInfo['userId'];
            $countryName = empty($countryInfo) ? '' : $countryInfo['streetName'];
        }

        //获取市代
        $cityInfo = $this->getAgencyInfo($cityId, 2);
        $cityUid  = empty($cityInfo) ? 0 : $cityInfo['userId'];
        $cityName = empty($cityInfo) ? '' : $cityInfo['cityName'];

        //获取省代
        $provinceInfo = $this->getAgencyInfo($provinceId, 1);
        $provinceUid  = empty($provinceInfo) ? 0 : $provinceInfo['userId'];
        $provinceName = empty($provinceInfo) ? '' : $provinceInfo['provinceName'];

        return [
            'provinceUid'  => $provinceUid,
            'cityUid'      => $cityUid,
            'countryUid'   => $countryUid,
            'provinceName' => $provinceName,
            'cityName'     => $cityName,
            'countryName'  => $countryName,
        ];
    }

    public function sync($data): bool
    {
        if (empty($data)) {
            return false;
        }
        try {
            switch ($data['type']) {
                case 'member':
                    $this->setMemberInfo($data['data']['id']);
                    break;
                case 'shop_comment':
                    ShopService::getInstance()->shopComment($data['data']['id'], $data['data']['serve_score'], $data['data']['environment_score'], $data['data']['cost_score']);
                    break;
                case 'gxz':
                    $this->sendGxz($data['data']['id']);
                    break;
                case 'real_name':
                    $this->sendNewTaskGxz($data['data']['id'], 'real_name', '实名认证，赠送贡献值');
                    break;
                case 'sign_in':
                    $this->signIn($data['data']['id']);
                    break;
                case 'task_for_adv':
                    CommunityService::getInstance()->taskForAdv($data['data']['userId'],$data['data']['communityId'],$data['data']['orderId']);
                    break;
                case 'member_click':
                    MemberInfoService::getInstance()->memberClick($data['data']['id'],$data['data']['device'],$data['data']['phone']);
                    break;
                case 'community_sign':
                    CommunityService::getInstance()->addCommunitySign($data['data']['id']);
                    break;
                case 'lottery_add':
                    //赠送抽奖次数
                    LotteryService::getInstance()->send($data['data']['id'],1);
                    break;
                default:
            }
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return false;
        }
        return true;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function setMemberInfo($userId): bool
    {
        $userData = Member::getInstance()
            ->where('id', '=', $userId)
            ->find();
        if (empty($userData)) {
            return false;
        }
        //更新抢购社区次数
        CommunityService::getInstance()->userCanCount($userId);

        //更新上级抢购社区次数
        if ($userData['inviteId']) {
            CommunityService::getInstance()->userCanCount($userData['inviteId']);
        }
        //更新用户账号
        MemberAccountCache::setKeyData($userId);

        //活跃值
        $this->setActive($userData['inviteId'], 3, 1, 1);

        // 检查邀请人会员等级升级
        if ($userData['inviteId']) {
            try {
                \app\api\services\UserLevelService::getInstance()->checkUpgrade(
                    $userData['inviteId']
                );
            } catch (\Exception $e) {
                \think\facade\Log::error($e->getMessage());
            }
            $inviteId2 = \think\facade\Db::table('member')
                ->where('id', $userData['inviteId'])
                ->value('invite_id');
            // 检查邀请人的邀请人会员等级升级
            if ($inviteId2) {
                try {
                    \app\api\services\UserLevelService::getInstance()->checkUpgrade(
                        $inviteId2
                    );
                } catch (\Exception $e) {
                    \think\facade\Log::error($e->getMessage());
                }
            }
        }

        //同一社区推荐多少会员或多少商家，可赠送社区合伙人
        $user = Marketing::getKeyData('invite', 'user');
        if(isset($user['community_same_num']) && $user['community_same_num'] > 0){
            $where = [
                ['invite_id','=',$userData['inviteId']],
            ];
            $list = Member::getInstance()->where($where)->field('count(*) comm_count,comm_id')->group('comm_id')->select();
            foreach($list as $v){
                if($v['commCount'] >= $user['community_same_num']){
                    $config = CommunityService::getInstance()->getCommunityConfig('buy_community_config');
                    $this->createCommunityUser($v['commId'],$userData['inviteId'],$config['buy_price']);
                }
            }
        }
        //新增或更新用户推荐管理
        if($userData['inviteId']){
            $this->statsInviteManage(date('Y-m-d'),$userData['inviteId']);
        }
        return true;
    }

    public function statsInviteManage($date,$userId): bool
    {
        $end = $date . ' 23:59:59';
        try{
            //会员直推荐会员的人数
            $where = [
                ['invite_id','=',$userId],
                ['create_at','between', [$date, $end]]
            ];
            $userNum = Member::getInstance()->where($where)->count();

            $where = [
                ['invite_id','=',$userId],
                ['create_at','between', [$date, $end]]
            ];

            //直推荐会员实名认证的人数
            $ids = Member::getInstance()->where($where)->column('id');
            $where = [
                ['user_id','in',implode(',',$ids)],

            ];
            $whereOr = [
                ['idc','<>',''],
            ];
            $userRealNum = Account::getInstance()->where($where)->where(function ($query) use ($whereOr) {
                $query->whereOr($whereOr)->whereOr('idc is not null');
            })->count();

            //团队新增人数
            $teamNum = Member::getInstance()
                ->whereLike('invite_ids','%-'.$userId.'-%')
                ->where('create_at','between',[$date, $end])
                ->count();

            //团队实名人数
            $teamRealNum = Member::getInstance()->alias('m')
                ->leftJoin('member_account a','m.id=a.user_id')
                ->whereLike('m.invite_ids','%-'.$userId.'-%')
                ->where('m.create_at','between',[$date, $end])
                ->where(function ($query) use ($whereOr) {
                    $query->whereOr('a.idc', '<>' , '')->whereOr('a.idc is not null');
                })->count();

            //直推商家数
            $where = [
                ['is_shop','=',1],
                ['invite_id','=',$userId],
                ['create_at','between', [$date, $end]]
            ];
            $shopNum = Member::getInstance()->where($where)->count();

            //团队商家数
            $teamShopNum = Member::getInstance()
                ->where('is_shop',1)
                ->whereLike('invite_ids','%-'.$userId.'-%')
                ->where('create_at','between',[$date, $end])
                ->count();

            //今日直推参与社区人数
            $where = [
                ['m.invite_id','=',$userId],
                ['o.status','=',CommunityConst::ORDER_PAY],
                ['o.create_at','between', [$date, $end]]
            ];
            $inviteCommunityNum = CommunityOrder::getInstance()
                ->alias('o')
                ->leftJoin('member m','o.user_id=m.id')
                ->where($where)
                ->count();

            //今日团队会员参与社区人数
            $inviteTeamCommunityNum = CommunityOrder::getInstance()
                ->alias('o')
                ->leftJoin('member m','o.user_id=m.id')
                ->whereLike('m.invite_ids','%-'.$userId.'-%')
                ->where('o.create_at','between',[$date, $end])
                ->where('o.status',CommunityConst::ORDER_PAY)
                ->count('DISTINCT o.user_id');


            //直推商家营业额
            $where = [
                ['is_shop','=',1],
                ['invite_id','=',$userId],
                ['create_at','between', [$date, $end]]
            ];
            $shopUserIds = Member::getInstance()->where($where)->column('id');
            $shopIds = Shop::getInstance()->where('user_id','in',$shopUserIds)->column('id');
            //1待发货 2待收款 3已收货 4已完成
            $inviteShopMoney = OrderShop::getInstance()
                ->where('shop_id','in',$shopIds)
                ->where('status','in',[1,2,3,4])
                ->where('create_at','between',[$date, $end])
                ->sum('pay_price') ?: 0;
            if($userNum <= 0 && $userRealNum <= 0 && $teamNum <= 0 && $teamRealNum <= 0 && $shopNum <= 0 && $teamShopNum <= 0 && $inviteCommunityNum <= 0 && $inviteTeamCommunityNum <= 0 && $inviteShopMoney <= 0){
                return false;
            }
            $data = [
                'user_num' => $userNum,
                'user_real_num' => $userRealNum,
                'team_num' => $teamNum,
                'team_real_num' => $teamRealNum,
                'shop_num' => $shopNum,
                'team_shop_num' => $teamShopNum,
                'invite_community_num' => $inviteCommunityNum,
                'invite_team_community_num' => $inviteTeamCommunityNum,
                'invite_shop_money' => $inviteShopMoney,
                'user_id' => $userId,
                'date' => $date,
            ];
            $where = [
                ['date','=',$date],
                ['user_id','=',$userId]
            ];
            $ret = StatsInviteManage::getInstance()->where($where)->find();
            if($ret){
                $data['update_at'] = date('Y-m-d H:i:s');
                StatsInviteManage::getInstance()->where($where)->update($data);
            }else{
                StatsInviteManage::getInstance()->insert($data);
            }
        }catch (\Exception $ex){
            Log::error($ex->getMessage().$ex->getFile().$ex->getLine());
        }
        return true;
    }

    public function createCommunityUser($communityId, $userId, $price): bool
    {
        $community = Community::getInstance()->where('comm_id',$communityId)->find();
        if(empty($community)){
            return false;
        }
        if($community->lock_status == 2){
            return false;
        }
        $community->lock_status = 2;
        $community->save();
        $data = [
            'community_name' => $community['name'],
            'community_id' => $community['id'],
            'address' => $community['province'] . $community['city'] . $community['country'] . $community['street'],
            'user_id' => $userId,
            'last_enter_amount' => $price,
            'last_enter_time' => date('Y-m-d H:i:s'),
            'community_status' => CommunityConst::PERMANENT_STATUS,
            'lock_status' => CommunityConst::LOCK,
            'last_order_id' => 0,
            'is_pay_service' => 0,
            'total_amount' => $price,
            'activity_id' => 0,
            'type' => 3, //招募广场
        ];
        CommunityUser::getInstance()->insert($data);
        $data = [
            'community_name' => $community['name'],
            'community_id' => $community['id'],
            'user_id' => $userId,
            'remark' => '邀请会员赠送',
        ];
        \app\common\models\Community\SendCommunityUser::getInstance()->insert($data);
        return true;
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function sendGxz($userId): bool
    {
        $userData = Member::getInstance()
            ->where('id', '=', $userId)
            ->find();
        if (empty($userData)) {
            return false;
        }
        //更新抢购社区次数
        CommunityService::getInstance()->userCanCount($userId);

        if ($userData['inviteId']) {
            //邀请人获得赠送贡献值
            $msg  = '邀请会员，(' . substr_replace($userData['phone'], '****', 3, 4) . ')，赠送贡献值';
            $data = Marketing::getKeyData('invite', 'user');
            if ($data) {
                $count = Member::getInstance()->where('invite_id', $userData['inviteId'])->count();
                if ($data['limit'] == 0 || $count <= $data['limit']) {
                    $time = date('Y-m-d');
                    if ($data['status'] == 1 && ($time >= $data['start_time'] && $time <= $data['end_time'])) {
                        MemberService::getInstance()->addFinanceLog($userData['inviteId'], 'invite_user', $data['gxz_value'], 7, $msg);
                    }
                }
            }
        }

        //新人注册获得赠送贡献值
        $data = Marketing::getKeyData('marketing', 'reg');
        if ($data) {
            if ($data['status'] == 1) {
                $msg = '新人注册，赠送贡献值';
                MemberService::getInstance()->addFinanceLog($userId, 'reg_user', $data['send_gxz'], 7, $msg);
            }
        }

        return true;
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function sendNewTaskGxz($userId, $field, $msg): bool
    {
        $userData = Member::getInstance()
            ->where('id', '=', $userId)
            ->find();
        if (empty($userData)) {
            return false;
        }

        $data = Marketing::getKeyData('task', 'new');
        if ($data[$field] > 0) {
            MemberService::getInstance()->addFinanceLog($userId, $field, $data[$field], 7, $msg);
        }
        MemberAccountCache::setKeyData($userId);
        return true;
    }

    /**
     * @param $userId
     * @param $orderPrice
     * @param $orderNo
     * @param $profit
     * @param $type 1线上订单 2线下订单 3怡亚通订单 4社区订单 5礼包订单
     * @return bool
     */
    public function profitPoolLog($userId, $orderPrice, $orderNo, $profit, $type): bool
    {
        $data = Marketing::getKeyData('profit', 'pool');
        if (empty($data)) {
            return false;
        }
        if ($data['status'] != 1) {
            return false;
        }
        if ($profit <= 0) {
            return false;
        }
        if ( ! in_array($type, [1, 2, 3, 4, 5, 6, 7, 8])) {
            return false;
        }
        //1线上订单 2线下订单 3怡亚通订单 4社区订单 5礼包订单 6无忧订单 7会员卡 8生活馆
        $rate = [
            1 => $data['online_rate'] ?? 0,
            2 => $data['offline_rate'] ?? 0,
            3 => $data['supply_rate'] ?? 0,
            4 => $data['premium_rate'] ?? 0,
            5 => $data['packs_rate'] ?? 0,
            6 => $data['carefree_rate'] ?? 0,
            7 => $data['card_rate'] ?? 0,
            8 => $data['service_rate'] ?? 0,
        ];

        $amount = bcmul($profit, bcmul($rate[$type] ?? 0, 0.01, 4), 4);
        if ($amount <= 0) {
            return false;
        }
        $data = [
            'order_no'    => $orderNo,
            'user_id'     => $userId,
            'order_price' => $orderPrice,
            'profit'      => $profit,
            'amount'      => $amount,
            'rate'        => $rate[$type],
            'type'        => $type,
        ];
        MemberProfitPoolLog::getInstance()->insert($data);
        return true;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function signIn($id): bool
    {
        $info = MemberSignInLog::getInstance()->where('id', $id)->find();
        if ( ! $info) {
            return false;
        }
        if ($info['status'] == 1) {
            return false;
        }
        $signIn = Marketing::getKeyData('signin', 'signin_set');
        if (empty($signIn)) {
            return false;
        }
        if ($signIn['status'] != 1) {
            return false;
        }
        $data = [];
        if ($info['successions'] <= 1 || empty($signIn['continue'])) {
            $data = ['gxz_value' => $signIn['gxz_value'], 'growth_value' => ['growth_value'], 'lang_score' => $signIn['lang_score']];
        } else {
            foreach ($signIn['continue'] as $v) {
                if ($v['day'] == $info['successions']) {
                    $data = $v;
                    break;
                }
            }
            //没有设置对应的连续天数，取默认值
            if (empty($data)) {
                $data = ['gxz_value' => $signIn['gxz_value'], 'growth_value' => ['growth_value'], 'lang_score' => $signIn['lang_score']];
            }
        }
        if ($data['gxz_value'] > 0) {
            $msg = '签到，赠送贡献值';
            MemberService::getInstance()->addFinanceLog($info['userId'], 'sign_in', $data['gxz_value'], 7, $msg);
        }
        if ($data['growth_value'] > 0) {

        }
        if ($data['lang_score'] > 0) {

        }
        MemberSignInLog::getInstance()->where('id', $id)->update(['status' => 1, 'update_at' => date('Y-m-d H:i:s')]);

        //连续签到奖励活跃值
        $this->setActive($info['userId'], 1, 1);
        return true;
    }

    /**
     * $type 1签到 2消费
     * $calType 1连续 2不连续
     * $taskType 1推荐会员 2推荐商家 3看广告
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function setActive($userId, $type, $calType, $taskType = 0, $order_no = ''): bool
    {
        if (empty($userId)) {
            return false;
        }
        $data = Marketing::getKeyData('active', 'active_set');
        if (empty($data)) {
            return false;
        }
        $finance = Finance::getInstance()->where('user_id', $userId)->find();
        if (empty($finance)) {
            return false;
        }
        if ($type == 1 && $calType == 1 && $finance['activity'] >= 100) {
            return false;
        }
        switch ($type) {
            case 1:
                //签到
                if ( ! empty($data['sign_data'])) {
                    foreach ($data['sign_data'] as $v) {
                        if ( ! isset($v['is_yes']) || empty($v['num']) || empty($v['award_num'])) {
                            continue;
                        }
                        $lastData    = MemberSignInLog::getInstance()->where('user_id', $userId)->order('create_at', 'desc')->find();
                        $yesterday   = date('Y-m-d', strtotime('-1 day'));
                        $successions = $lastData && $lastData['createAt'] > $yesterday ? $lastData['activity_successions'] : 0;
                        if ($calType == 1) {
                            if ($successions != $v['num']) {
                                continue;
                            }
                            if ($v['is_yes'] == 1) {
                                $this->addActivityAmountInfo($finance, 'sign_in', $v['award_num'], '连续签到');
                            }
                        } else {
                            if ($v['is_yes'] != 0) {
                                continue;
                            }
                            $day   = $v['num'];
                            $start = date('Y-m-d 00:00:00', strtotime("-{$day} day"));
                            $end   = date('Y-m-d 23:59:59', strtotime('-1 day'));
                            $where = [
                                ['user_id', '=', $userId],
                                ['deleted', '=', 0],
                                ['status', '=', 1],
                                ['create_at', 'between', [$start, $end]],
                            ];
                            $count = MemberSignInLog::getInstance()->where($where)->count();
                            if($count > 0){
                                continue;
                            }

                            $day   = $v['num'] - 1;
                            $start = date('Y-m-d 00:00:00', strtotime("-{$day} day"));
                            $end   = date('Y-m-d 23:59:59', strtotime('-1 day'));
                            $where = [
                                ['user_id', '=', $userId],
                                ['log_type', 'in', ['sign_in_no', 'sign_in']],
                                ['deleted', '=', 0],
                                ['create_at', 'between', [$start, $end]],
                            ];
                            $count = MemberActivityLog::getInstance()->where($where)->count();
                            if ($count > 0) {
                                continue;
                            }

                            $this->addActivityAmountInfo($finance, 'sign_in_no', $v['award_num'], '连续不签到');
                        }
                    }
                }
                break;
            case 2:
                //消费
                if ( ! empty($data['consume_data'])) {
                    foreach ($data['consume_data'] as $v) {
                        if ( ! isset($v['is_yes']) || empty($v['num']) || empty($v['award_num'])) {
                            continue;
                        }
                        if ($calType == 1) {
                            if ($v['is_yes'] != 1) {
                                continue;
                            }
                            $where = [
                                ['log_type', '=', 'consume'],
                                ['user_id', '=', $userId],
                            ];
                            $createAt = MemberActivityLog::getInstance()->where($where)->order('id desc')->value('create_at');
                            $where    = [
                                ['user_id', '=', $userId],
                                ['status', '=', 1],
                            ];
                            if ( ! empty($createAt)) {
                                $where[] = ['create_at', '>', $createAt];
                            }
                            $find       = OrderPay::getInstance()->where($where)->field('sum(pay_price) order_money,count(*) ct')->find();
                            $orderMoney = $find['orderMoney'] ?? 0;
                            if ($orderMoney <= 0) {
                                continue;
                            }
                            $count = $find['ct'] ?? 0;
                            $value = bcmul(bcdiv($orderMoney, $v['num'], 2), $v['award_num'], 2);
                            if ($value > 0 && $count >= $v['num']) {
                                $this->addActivityAmountInfo($finance, 'consume', $value, '连续消费');
                            }
                        } else {
                            if ($v['is_yes'] != 0) {
                                continue;
                            }
                            $day   = $v['num'];
                            $start = date('Y-m-d 00:00:00', strtotime("-{$day} day"));
                            $end   = date('Y-m-d 23:59:59', strtotime('-1 day'));
                            $where    = [
                                ['user_id', '=', $userId],
                                ['status', '=', 1],
                                ['create_at', 'between', [$start, $end]],
                            ];
                            $count = OrderPay::getInstance()->where($where)->count();
                            if ($count > 0) {
                                continue;
                            }

                            $day   = $v['num'] - 1;
                            $start = date('Y-m-d 00:00:00', strtotime("-{$day} day"));
                            $end   = date('Y-m-d 23:59:59', strtotime('-1 day'));

                            $where = [
                                ['log_type', 'in', ['consume_no', 'consume']],
                                ['user_id', '=', $userId],
                                ['create_at', 'between', [$start, $end]],
                            ];
                            $count = MemberActivityLog::getInstance()->where($where)->count();
                            if($count > 0){
                                continue;
                            }
                            $this->addActivityAmountInfo($finance, 'consume_no', $v['award_num'], '连续不消费');
                        }
                    }
                }
                break;
            case 3:
                if ( ! isset($data['status']) || $data['status'] != 1 || empty($data['task_data'])) {
                    break;
                }
                foreach ($data['task_data'] as $v) {
                    if ( ! isset($v['type']) || empty($v['num']) || empty($v['award_num'])) {
                        continue;
                    }
                    if ($calType == 1) {
                        if ($v['type'] == 1 && $taskType == 1) {
                            //推荐会员
                            $where = [
                                ['log_type', '=', 'invite_user'],
                                ['user_id', '=', $userId],
                            ];
                            $createAt = MemberActivityLog::getInstance()->where($where)->order('id desc')->value('create_at');
                            $where    = [
                                ['invite_id', '=', $userId],
                            ];
                            if ( ! empty($createAt)) {
                                $where[] = ['create_at', '>', $createAt];
                            }
                            $num = Member::getInstance()->where($where)->count();
                            if ($num < $v['num']) {
                                continue;
                            }
                            $this->addActivityAmountInfo($finance, 'invite_user', $v['award_num'], '推荐会员');
                        }
                        if ($v['type'] == 2 && $taskType == 2) {
                            //推荐商家
                            $where = [
                                ['log_type', '=', 'invite_shop'],
                                ['user_id', '=', $userId],
                            ];
                            $createAt = MemberActivityLog::getInstance()->where($where)->order('id desc')->value('create_at');
                            $where    = [
                                ['invite_id', '=', $userId],
                            ];
                            if ( ! empty($createAt)) {
                                $where[] = ['create_at', '>', $createAt];
                            }
                            $num = Member::getInstance()->where($where)->count();
                            if ($num < $v['num']) {
                                continue;
                            }
                            $this->addActivityAmountInfo($finance, 'invite_shop', $v['award_num'], '推荐商家');
                        }
                        if ($v['type'] == 3 && $taskType == 3) {
                            //看广告增加活跃值
                            $where = [
                                ['user_id', '=', $userId],
                                ['log_type', '=', 'adv'],
                                ['create_at', '>', date('Y-m-d')],
                            ];
                            $createAt = MemberActivityLog::getInstance()->where($where)->order('id desc')->value('create_at');
                            if ( ! empty($createAt)) {
                                $where[] = ['create_at', '>', $createAt];
                            }
                            $num = MemberGxzLog::getInstance()->where($where)->count();
                            if ($num < $v['num']) {
                                continue;
                            }
                            $this->addActivityAmountInfo($finance, 'adv', $v['award_num'], '看广告');
                        }
                    }
                }
                break;
            default:
        }
        return true;
    }

    /**
     * 按贡献值加权分
     * @param $data
     * @param $output
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function gxzProfit($data, $output): bool
    {
        if (empty($data)) {
            return false;
        }
        //分润池金额
        $profitPoolMoney = MemberProfitPoolLog::getInstance()->where('status', 1)->sum('amount') ?: 0;
        if ($profitPoolMoney <= 0) {
            return false;
        }

        //0表示不兜底，大于0表示分润池中金额低于该数字就不再分润
        if ($data['di_money'] <= 0) {
            return false;
        }

        //可分润金额 = 分润池金额 - 已分金额
        $amountIssued    = MemberProfitLog::getInstance()->where('status', 1)->sum('amount') ?: '0.00';
        $profitPoolMoney = bcsub((string) $profitPoolMoney, (string) $amountIssued, 4);
        if ($profitPoolMoney < $data['di_money']) {
            return false;
        }
        $whereOr = [];
        //会员贡献值
        if ($data['type'] == 0) {
            $where = [
                ['f.gxz', '>=', $data['gxz']],
                ['m.deleted', '=', 0],
            ];
        } else {
            //会员等级
            if (in_array(0, $data['level'])) {
                //全部会员贡献员
                $where = [
                    ['m.deleted', '=', 0],
                ];
            } else {
                //等级贡献值
                //服务商
                $where = [];
                if(in_array(2, $data['level'])){
                    $where = [
                        ['m.deleted', '=', 0],
                        ['m.is_partner', '=', 1]
                    ];
                }
                //代理
                if (in_array(3, $data['level'])) {
                    $whereOr = [
                        ['m.deleted', '=', 0],
                        ['m.is_agency', '>', 0],
                    ];
                }

            }
        }

        $gxzTotal = Member::getInstance()->alias('m')
            ->leftJoin('member_finance f', 'm.id=f.user_id')
            ->where($where)
            ->whereOr(function ($query) use ($whereOr) {
                $query->where($whereOr);
            })
            ->sum('f.gxz') ?: "0.00";

        $ret = Member::getInstance()->alias('m')
            ->leftJoin('member_finance f', 'm.id=f.user_id')
            ->where($where)
            ->whereOr(function ($query) use ($whereOr) {
                $query->where($whereOr);
            })
            ->field('f.gxz,m.id')
            ->select();

        $output->writeln('开始：' . date('Y-m-d H:i:s'));
        $count = 1;
        foreach ($ret as $v) {
            $output->writeln((string) $count++);

            //贡献值递减
            if ($data['profit_mode'] == 1) {
                $map = [
                    ['user_id', '=', $v['userId']],
                    ['status', '=', 1],
                ];
                $amount   = MemberProfitLog::getInstance()->where($map)->sum('amount') ?: 0;
                $v['gxz'] = bcsub($v['gxz'], $amount, 4);
            }

            if ($v['gxz'] <= 0) {
                continue;
            }
            //每期(每周一)个人获得分红公式:(分润池*10%(每期分红比例)/平台总贡献值)*个人贡献值(个人参与分红贡献值需大于1000)
            $rate        = $data['rate'] * 0.01;
            $everyAmount = bcdiv(bcmul((string) $profitPoolMoney, (string) $rate, 4), (string) $gxzTotal, 4);
            $profit      = bcmul($everyAmount, $v['gxz'], 4);
            $output->writeln('当前账号可分金额：' . $profit);
            if ($profit <= 0) {
                continue;
            }

            MemberProfitLog::getInstance()->startTrans();
            try {
                $dataArr = [
                    'user_id'            => $v['id'],
                    'rate'               => $data['rate'],
                    'gxz'                => $v['gxz'],
                    'profit_pool_amount' => bcadd((string) $profitPoolMoney, "0", 4),
                    'every_amount'       => $everyAmount,
                    'amount'             => $profit,
                ];
                MemberProfitLog::getInstance()->insert($dataArr);
                MemberService::getInstance()->addFinanceLog($v['id'], 'add', $profit, 5, $msg = '获得贡献值分红', $orderNo = '', 1, 3);
                Finance::getInstance()->where('user_id', $v['id'])->inc('all_bonus', (float) $profit)->update();
                Finance::getInstance()->where('user_id', $v['id'])->update(['day_bonus' => $profit]);
                $output->writeln('user_id：' . $v['id'] . ' 分润收益：' . $profit);
            } catch (\Exception $e) {
                $output->writeln($e->getMessage());
                MemberProfitLog::getInstance()->rollback();
            }
            MemberProfitLog::getInstance()->commit();
        }
        return true;
    }

    /**
     * 按会员等级分
     * @param $data
     * @param $output
     * @return false|void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function levelProfit($data, $output)
    {
        if (empty($data)) {
            return false;
        }
        if (empty($data['data'])) {
            return false;
        }
        if ($data['get_type'] != 1) {
            return false;
        }
        $where = [
            ['m.status', '=', 1],
            ['m.is_logout', '=', 0],
            ['m.deleted', '=', 0],
        ];
        $page     = 1;
        $pageSize = 100;
        $count    = Member::getInstance()->alias('m')
            ->leftJoin('member_finance f', 'm.id=f.user_id')
            ->field('m.*,f.activity')
            ->where($where)
            ->count();
        //总页数
        $total = ceil($count / $pageSize);
        //统计数量
        $num = 0;
        $output->writeln('开始：' . date('Y-m-d H:i:s'));
        while ($page <= $total) {
            $list = Member::getInstance()->alias('m')
                ->leftJoin('member_finance f', 'm.id=f.user_id')
                ->field('m.*,f.activity,f.gxz')
                ->where($where)
                ->page($page, $pageSize)
                ->select();
            foreach ($list as $v) {
                $num++;
                $output->writeln('当前用户数量：' . $num);
                if ($v['gxz'] <= 0) {
                    continue;
                }
                $range = [];
                foreach ($data['data'] as $vv) {
                    if (empty($vv)) {
                        continue;
                    }
                    if ($vv['is_yes'] == 0) {
                        continue;
                    }
                    list($start, $end) = explode('-', $vv['name']);
                    if ($v['activity'] >= $start && $v['activity'] <= $end) {
                        $range = $vv;
                        break;
                    }
                }
                if (empty($range)) {
                    continue;
                }
                $map = [
                    ['number', '=', $v['level']],
                    ['status', '=', 1],
                ];
                $rewardRule = BaseUserUpgrade::getInstance()->where($map)->value('reward_rule');
                if (empty($rewardRule)) {
                    continue;
                }
                $rewardRule = json_decode($rewardRule, true);
                if ( ! isset($rewardRule['dividend_basis']) || $rewardRule['dividend_basis'] <= 0) {
                    continue;
                }
                //动态分润计算公式 ：（动态分红比例/100*活路值）*分红基数*贡献值
                //固定分红：只要活路值在该范围内，都按固定比例分红，计算公式 为 固定比例/100*分红基数*贡献值
                if ($range['award_type'] == 1) {
                    $rate       = $range['fix_rate'];
                    $profitRate = bcmul($rate * 0.01, $rewardRule['dividend_basis'] * 0.0001, 5);
                    $profit     = bcmul($profitRate, $v['gxz'], 4);
                } else {
                    $rate       = $range['dynamic_rate'];
                    $profitRate = bcmul(bcmul($rate * 0.01, $v['activity'], 5), $rewardRule['dividend_basis'] * 0.0001, 5);
                    $profit     = bcmul($profitRate, $v['gxz'], 4);
                }
                if ($profit <= 0) {
                    continue;
                }

                MemberProfitLog::getInstance()->startTrans();
                try {
                    $everyAmount = bcdiv($profit, $v['gxz'], 4);
                    $dataArr     = [
                        'user_id'            => $v['id'],
                        'rate'               => $rate,
                        'gxz'                => $v['gxz'],
                        'profit_pool_amount' => 0,
                        'every_amount'       => $everyAmount,
                        'amount'             => $profit,
                    ];
                    MemberProfitLog::getInstance()->insert($dataArr);
                    MemberService::getInstance()->addFinanceLog($v['id'], 'add', $profit, 5, $msg = '获得贡献值分红', $orderNo = '', 1, 3);
                    Finance::getInstance()->where('user_id', $v['id'])->inc('all_bonus', (float) $profit)->update();
                    Finance::getInstance()->where('user_id', $v['id'])->update(['day_bonus' => $profit]);
                    if ($data['profit_mode'] == 1) {
                        //递减
                        MemberService::getInstance()->addFinanceLog($v['id'], 'profit_sub', $profit, 7, '分红扣除贡献值');
                    }
                } catch (\Exception $e) {
                    MemberProfitLog::getInstance()->rollback();
                    Log::error($e->getMessage());
                }
                MemberProfitLog::getInstance()->commit();
            }
            $page++;
        }
        $output->writeln('处理分润数量：' . $num);
    }

    /**
     * @param $userId
     * @param int $specialId
     * @param array $goodsIdArr
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function recoverActivity($userId, int $specialId = 0, array $goodsIdArr = []): bool
    {
        $data = Marketing::getKeyData('profit', 'set');
        if (empty($data)) {
            return false;
        }
        if (!isset($data['is_active']) || $data['is_active'] != 1) {
            return false;
        }
        //1购买指定商品 2购买指定专区
        if ($data['buy_type'] == 1) {
            if (empty($data['buy_product_id'])) {
                return false;
            }
            if (empty($goodsIdArr)) {
                return false;
            }
            if ( ! in_array($data['buy_product_id'], $goodsIdArr)) {
                return false;
            }
            $type = 'goods';
            $msg  = '购买商品';
        } else {
            if (empty($data['buy_special_id'])) {
                return false;
            }
            if ($specialId != $data['buy_special_id']) {
                return false;
            }
            $type = 'special';
            $msg  = '购买专题商品';
        }
        if (empty($data['active_value'])) {
            return false;
        }
        $finance = Finance::getInstance()->where('user_id', $userId)->find();
        if (empty($finance)) {
            return false;
        }
        if ($finance['activity'] >= $data['active_value']) {
            return false;
        }
        $activity = bcsub($data['active_value'], $finance['activity'], 2);
        $this->addActivityAmountInfo($finance, $type, $activity, $msg);
        return true;
    }

    /**
     * 手动会员等级分
     * @param $data
     * @param $userId
     * @return false|string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getLevelProfit($data, $userId)
    {
        $finance = Finance::getInstance()->where('user_id', $userId)->find();
        if ($finance['gxz'] <= 0) {
            return false;
        }
        $range = [];
        foreach ($data['data'] as $vv) {
            if (empty($vv)) {
                continue;
            }
            if ($vv['is_yes'] == 0) {
                continue;
            }
            list($start, $end) = explode('-', $vv['name']);
            if ($finance['activity'] >= $start && $finance['activity'] <= $end) {
                $range = $vv;
                break;
            }
        }
        if (empty($range)) {
            return false;
        }
        $level = Member::getInstance()->where('id', $userId)->value('level');
        $map   = [
            ['number', '=', $level],
            ['status', '=', 1],
        ];
        $rewardRule = BaseUserUpgrade::getInstance()->where($map)->value('reward_rule');
        if (empty($rewardRule)) {
            return false;
        }
        $rewardRule = json_decode($rewardRule, true);
        if ( ! isset($rewardRule['dividend_basis']) || $rewardRule['dividend_basis'] <= 0) {
            return false;
        }
        //动态分润计算公式 ：（动态分红比例/100*活路值）*分红基数*贡献值
        //固定分红：只要活路值在该范围内，都按固定比例分红，计算公式 为 固定比例/100*分红基数*贡献值
        if ($range['award_type'] == 1) {
            $rate       = $range['fix_rate'];
            $profitRate = bcmul($rate * 0.01, $rewardRule['dividend_basis'] * 0.0001, 5);
            $profit     = bcmul($profitRate, $finance['gxz'], 4);
        } else {
            $rate       = $range['dynamic_rate'];
            $profitRate = bcmul(bcmul($rate * 0.01, $finance['activity'], 5), $rewardRule['dividend_basis'] * 0.0001, 5);
            $profit     = bcmul($profitRate, $finance['gxz'], 4);
        }
        if ($profit <= 0) {
            return false;
        }

        MemberProfitLog::getInstance()->startTrans();
        try {
            $everyAmount = bcdiv($profit, $finance['gxz'], 4);
            $dataArr     = [
                'user_id'            => $userId,
                'rate'               => $rate,
                'gxz'                => $finance['gxz'],
                'profit_pool_amount' => 0,
                'every_amount'       => $everyAmount,
                'amount'             => $profit,
            ];
            MemberProfitLog::getInstance()->insert($dataArr);
            MemberService::getInstance()->addFinanceLog($userId, 'add', $profit, 5, $msg = '获得贡献值分红', $orderNo = '', 1, 3);
            Finance::getInstance()->where('user_id', $userId)->inc('all_bonus', (float) $profit)->update();
            Finance::getInstance()->where('user_id', $userId)->update(['day_bonus' => $profit]);
            if ($data['profit_mode'] == 1) {
                //递减
                MemberService::getInstance()->addFinanceLog($userId, 'profit_sub', $profit, 7, '分红扣除贡献值');
            }
        } catch (\Exception $e) {
            MemberProfitLog::getInstance()->rollback();
            Log::error($e->getMessage());
            return false;
        }
        MemberProfitLog::getInstance()->commit();
        return $profit;
    }

    public function isLevelProfit($data, $userId): bool
    {
        $finance = Finance::getInstance()->where('user_id', $userId)->find();
        if ($finance['gxz'] <= 0) {
            return false;
        }
        if(empty($data['data'])){
            return false;
        }
        $range = [];
        foreach ($data['data'] as $vv) {
            if (empty($vv)) {
                continue;
            }
            if ($vv['is_yes'] == 0) {
                continue;
            }
            list($start, $end) = explode('-', $vv['name']);
            if ($finance['activity'] >= $start && $finance['activity'] <= $end) {
                $range = $vv;
                break;
            }
        }
        if (empty($range)) {
            return false;
        }
        $level = Member::getInstance()->where('id', $userId)->value('level');
        $map = [
            ['number', '=', $level],
            ['status', '=', 1],
        ];
        $rewardRule = BaseUserUpgrade::getInstance()->where($map)->value('reward_rule');
        if (empty($rewardRule)) {
            return false;
        }
        $rewardRule = json_decode($rewardRule, true);
        if (!isset($rewardRule['dividend_basis']) || $rewardRule['dividend_basis'] <= 0) {
            return false;
        }
        //动态分润计算公式 ：（动态分红比例/100*活路值）*分红基数*贡献值
        //固定分红：只要活路值在该范围内，都按固定比例分红，计算公式 为 固定比例/100*分红基数*贡献值
        if ($range['award_type'] == 1) {
            $rate = $range['fix_rate'];
            $profitRate = bcmul($rate * 0.01, $rewardRule['dividend_basis'] * 0.0001, 5);
            $profit = bcmul($profitRate, $finance['gxz'], 4);
        } else {
            $rate = $range['dynamic_rate'];
            $profitRate = bcmul(bcmul($rate * 0.01, $finance['activity'], 5), $rewardRule['dividend_basis'] * 0.0001, 5);
            $profit = bcmul($profitRate, $finance['gxz'], 4);
        }
        if ($profit <= 0) {
            return false;
        }
        return true;
    }


    /**
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws DataNotFoundException
     */
    public function getGxzProfit($data, $userId)
    {
        //分润池金额
        $profitPoolMoney = MemberProfitPoolLog::getInstance()->where('status', 1)->sum('amount') ?: 0;
        if ($profitPoolMoney <= 0) {
            return false;
        }

        //0表示不兜底，大于0表示分润池中金额低于该数字就不再分润
        if ($data['di_money'] <= 0) {
            return false;
        }

        //可分润金额 = 分润池金额 - 已分金额
        $amountIssued    = MemberProfitLog::getInstance()->where('status', 1)->sum('amount') ?: '0.00';
        $profitPoolMoney = bcsub((string) $profitPoolMoney, (string) $amountIssued, 4);
        if ($profitPoolMoney < $data['di_money']) {
            return false;
        }
        $whereOr = [];
        //会员贡献值
        if ($data['type'] == 0) {
            $where = [
                ['f.gxz', '>=', $data['gxz']],
                ['m.deleted', '=', 0],
            ];
        } else {
            //会员等级
            if (in_array(0, $data['level'])) {
                //全部会员贡献员
                $where = [
                    ['m.deleted', '=', 0],
                ];
            } else {
                //等级贡献值
                //服务商
                $where = [];
                if(in_array(2, $data['level'])){
                    $where = [
                        ['m.deleted', '=', 0],
                        ['m.is_partner', '=', 1]
                    ];
                }
                //代理
                if (in_array(3, $data['level'])) {
                    $whereOr = [
                        ['m.deleted', '=', 0],
                        ['m.is_agency', '>', 0],
                    ];
                }

            }
        }

        $gxzTotal = Member::getInstance()->alias('m')
            ->leftJoin('member_finance f', 'm.id=f.user_id')
            ->where($where)
            ->whereOr(function ($query) use ($whereOr) {
                $query->where($whereOr);
            })
            ->sum('f.gxz') ?: "0.00";

        $ret = Member::getInstance()->alias('m')
            ->leftJoin('member_finance f', 'm.id=f.user_id')
            ->where('m.id', $userId)
            ->where($where)
            ->whereOr(function ($query) use ($whereOr) {
                $query->where($whereOr);
            })
            ->field('f.gxz,m.id')
            ->find();

        //贡献值递减
        if ($data['profit_mode'] == 1) {
            $map = [
                ['user_id', '=', $userId],
                ['status', '=', 1],
            ];
            $amount   = MemberProfitLog::getInstance()->where($map)->sum('amount') ?: 0;
            $ret['gxz'] = bcsub($ret['gxz'], $amount, 4);
        }

        if ($ret['gxz'] <= 0) {
            return false;
        }
        //每期(每周一)个人获得分红公式:(分润池*10%(每期分红比例)/平台总贡献值)*个人贡献值(个人参与分红贡献值需大于1000)
        $rate        = $data['rate'] * 0.01;
        $everyAmount = bcdiv(bcmul($profitPoolMoney, $rate, 4), (string) $gxzTotal, 4);
        $profit      = bcmul($everyAmount, $ret['gxz'], 4);
        if ($profit <= 0) {
            return false;
        }

        MemberProfitLog::getInstance()->startTrans();
        try {
            $dataArr = [
                'user_id'            => $userId,
                'rate'               => $data['rate'],
                'gxz'                => $ret['gxz'],
                'profit_pool_amount' => bcadd((string) $profitPoolMoney, "0", 4),
                'every_amount'       => $everyAmount,
                'amount'             => $profit,
            ];
            MemberProfitLog::getInstance()->insert($dataArr);
            MemberService::getInstance()->addFinanceLog($userId, 'add', $profit, 5, $msg = '获得贡献值分红', $orderNo = '', 1, 3);
            Finance::getInstance()->where('user_id', $userId)->inc('all_bonus', (float) $profit)->update();
            Finance::getInstance()->where('user_id', $userId)->update(['day_bonus' => $profit]);
            if ($data['profit_mode'] == 1) {
                //递减
                MemberService::getInstance()->addFinanceLog($userId, 'profit_sub', $profit, 7, '分红扣除贡献值');
            }
        } catch (\Exception $e) {
            echo $e->getMessage();
            MemberProfitLog::getInstance()->rollback();
        }
        MemberProfitLog::getInstance()->commit();
        return $profit;
    }



}
